﻿#region Disclaimer/Info
///////////////////////////////////////////////////////////////////////////////////////////////////
// MetaCollection
// 
// MetaCollection is a system to provide a standard structure, permissions and metadata service
// for content organization.
//
// This project is hosted at Google Code at http://code.google.com/p/metacollection/
//
// This project is licensed under the BSD license.  See the License.txt file for more information.
///////////////////////////////////////////////////////////////////////////////////////////////////
#endregion

using System;
using System.Collections.Generic;
using System.Diagnostics;
using MetaCollection.Framework.Model;
using MetaCollection.Framework.Provider;
using MetaCollection.Framework.Repository;
using System.IO;

namespace MetaCollection.Framework.Tests.Fakes
{
	public class FakeResourceProvider : IProvider
	{
		readonly object _SetEventLock = new object();
		private RequestEventTypes _setEvents;
        private string m_Description = "Provides an implementation of resource provider events that uses the standard Item and Resource repositories";
        private Guid m_Id = new Guid("{454C1903-9E23-4e82-BBB0-0F6E97EF4960}");
        private string m_Name = "ResourceProvider";

        public FakeResourceProvider()
        {

        }

		public FakeResourceProvider(RequestEventTypes supportedEvents)
		{
			SetEvents = RequestEventTypes.None;
			m_SupportedEvents = supportedEvents;
		}

		#region IProvider Members

		public Guid Id
		{
            get { return this.m_Id; }
            set { m_Id = value; }
		}

		public string Name
		{
            get { return this.m_Name; }
            set { m_Name = value; }
		}

		public string Description
		{
            get { return this.m_Description; }
            set { m_Description = value; }
		}

		public void Initialize(MetaCollection.Framework.Configuration.ProviderReferenceElement providerConfig)
		{

		}

		public RequestEventTypes SupportedEvents
		{
			get { return m_SupportedEvents; }
		}
		private RequestEventTypes m_SupportedEvents;
		public IEnumerable<IProviderType> DependantProviders
		{
			get;
			set;
		}

		#endregion

		/// <summary>
		/// Events which have been raised since the FakeResourceProvider was instantiated or ResetEvents was last called.
		/// </summary>
		public RequestEventTypes SetEvents
		{
			get
			{
				lock (_SetEventLock)
					return _setEvents;
			}
			private set
			{
				lock (_SetEventLock)
					_setEvents = value;
			}

		}
		/// <summary>
		/// Resets the SetEvents to None.
		/// </summary>
		public void ResetEvents()
		{
			SetEvents = RequestEventTypes.None;
		}


		#region IRequestSink Members


		public void OnRequestStart(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnRequestStart;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnRequestStart" + System.Environment.NewLine);
		}

		public void OnBeforeValidateRequest(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnBeforeValidateRequest;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnBeforeValidateRequest" + System.Environment.NewLine);
		}

		public void OnRequestValidateComplete(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnRequestValidateComplete;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnRequestValidateComplete" + System.Environment.NewLine);
		}

		public void OnBeforePathResolve(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnBeforePathResolve;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnBeforePathResolve" + System.Environment.NewLine);
		}

		public void OnPathResolveComplete(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnPathResolveComplete;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnPathResolveComplete" + System.Environment.NewLine);
		}

		public void OnBeforeInvokeRequest(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnBeforeInvokeRequest;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnBeforeInvokeRequest" + System.Environment.NewLine);
		}

		public void OnValidateRequest(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnValidateRequest;
			ItemContext context = sender as ItemContext;
			if (context == null)
				throw new InvalidOperationException("The Current Request Context of this request can not be null.");

			context.IsValidRequest = true;

			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnValidateRequest" + System.Environment.NewLine);
		}

		public void OnPathResolve(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnPathResolve;

			ItemContext context = sender as ItemContext;
			if (context == null)
				throw new InvalidOperationException("The Current Request Context of this request can not be null.");

			context.RequestPathResolved = true;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnPathResolve" + System.Environment.NewLine);
		}

		public void OnProvideItem(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnProvideItem;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnProvideItem" + System.Environment.NewLine);
		}

		public void OnProvideResource(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnProvideResource;
			ItemContext context = sender as ItemContext;
			if (context == null)
				throw new InvalidOperationException("The Current Request Context of this request can not be null.");
			context.ResponseResourceStream = Stream.Null;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnProvideResource" + System.Environment.NewLine);
		}

		public void OnHandlerDisposing(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnHandlerDisposing;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnHandlerDisposing" + System.Environment.NewLine);
		}

		public void OnRequestComplete(object sender, System.EventArgs args)
		{
			SetEvents = SetEvents | RequestEventTypes.OnRequestComplete;
			Debug.Write("FakeResourceProvider (" + m_SupportedEvents + "): OnRequestComplete" + System.Environment.NewLine);
		}

		#endregion
	}

	public class FakeResourceProviderType : IProviderType
	{
		public Guid Id { get; set; }
		/// <summary>
		/// Friendly Name of this specfic Provider Type instance (must be unique within a collection)
		/// </summary>
		public string Name { get; set; }
		/// <summary>
		/// A Description of the purpose of this provider type.
		/// </summary>
		public string Description { get; set; }
		/// <summary>
		/// A fully qualified assembly name to use when creating an instance
		/// of this provider.
		/// </summary>
		public string AssemblyName { get; set; }
		/// <summary>
		/// The specific type name within <see cref="AssemblyName"/> that extends
		/// <see cref="T:MetaCollection.Framework.Provider.ResourceProvider"/>
		/// </summary>
		public string TypeName { get; set; }
		/// <summary>
		/// Configuration information that will be passed into the provider
		/// instance when it is created.
		/// </summary>
		public string Config { get; set; }
	}
}
